#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <pthread.h>
#include <assert.h>

#include <event2/listener.h>
#include <event2/bufferevent.h>
#include <event2/event.h>
#include <event2/event_compat.h>
#include <event2/event_struct.h>
#include "server_detect.h"
#include "serv_socket_handle.h"
#include "log.h"
#include "user.h"
#include "userSqliteOp.h"

int main()
{
    struct event *udpEvent;
    struct evconnlistener *listener;
    struct event_base *eventBase = NULL;

    /* 1.设置日志信息与路径 */
    int err = init_log_file();
    assert(err == 0);
    
    err = server_file_path_init();
    assert(err == 0);
    

    eventBase = event_base_new();
    if (!eventBase)
    {
        add_log("event_base_new() error");
        exit(-1);
    }

    
    /* 2.服务器域名解析 */
    pthread_t tidDns;
    pthread_attr_t attr;
    err = pthread_attr_init(&attr);
    assert(err ==0);
    
    err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    assert(err == 0);
    
    err = pthread_create(&tidDns, &attr, create_file_dns_server, NULL);
    if (err != 0)
    {
        add_log("pthread_create() error");
        exit(-1);
    }
    pthread_attr_destroy(&attr);
    
	/* 3.初始化数据库 */
	int ret = initDatabase(DB_NAME);
    UTIL_ASSERT(ret == SUCCESS);

    
    /* 4.创建套接字 */
    int listenFd = create_tcp_sockfd(FILE_TRANS_TCP_PORT);
    assert(listenFd != -1);
    int udpFd = create_udp_sockfd(FILE_TRANS_UDP_PORT);
    assert(udpFd != -1);

    
    /* 5.设置事件并监听 */
    if (event_init() == NULL)
    {
        printf("event_init() failed\n");
        return -1;
    }
    
    udpEvent = event_new(eventBase, udpFd, EV_READ | EV_PERSIST, udp_read_cb, (void *)eventBase);
    if (!udpEvent || event_add(udpEvent, NULL) < 0)
    {
        printf("event_add() failed\n");
        exit(-1);
    }
    

    struct sockaddr_in sin;
    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(FILE_TRANS_TCP_PORT);
    

    listener = evconnlistener_new_bind(eventBase, new_connect_cb, (void *)eventBase,
                                       LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, -1,
                                       (struct sockaddr *)&sin,
                                       sizeof(sin));
    if (!listener)
    {
        fprintf(stderr, "Could not create a listener!\n");
        exit(-1);
    }

	/* 6.释放 */
    event_base_dispatch(eventBase);
    evconnlistener_free(listener);
    event_free(udpEvent);
    event_base_free(eventBase);
    return 0;
}